/* pipe.c: Implements basic piping in sea kernel */
/* Copyright (c) 2008 Daniel Bittman */
#include <common.h>
#include <isr.h>
#include <task.h>
#include <pipe.h>
int ids[TOTAL_PIPES];
extern task_t *current_task;

void init_piping()
{
	int i;
	for(i=0;i<TOTAL_PIPES+1;i++)ids[i]=0;
}

u32int create_pipe(pipe_t *p)
{
	cli();
	p=(pipe_t *)kmalloc(sizeof(pipe_t));
	int i, id=-1;
	for(i=0;i<TOTAL_PIPES+1;i++) {
		if(ids[i]==0)
		{
			id=i;
			break;
		}
	}
	if(id==-1)
		return -1;
	for(i=0;i<4096;i++)
		p->dat[i]=0;
	p->id=id;
	p->pid=current_task->id;
	ids[p->id]=1;
	p->rpos=p->wpos=0;
	p->auth=current_task->auth;
	//kprintf("CTA=%d, PA=%d\n", current_task->auth, p->auth);
	sti();
//	signal_all(SIG_NEW_PIPE, p);
	return 0;
}

int close_pipe(pipe_t *p)
{
	ids[p->id]=0;
	kfree(p);
}

int read_pipe(pipe_t *p, int len, char *buf)
{
	cli();
	int i, off=p->rpos;
	for(i=off;i<off+len;i++) {
		buf[i-off] = p->dat[i];
	//	p->dat[i]=0;
	}
	p->rpos=off+len;
	sti();
}

int write_pipe(pipe_t *p, char *data, int len)
{
	cli();
	//kprintf("CTA=%d, PA=%d\n", current_task->auth, p->auth);
	if(current_task->auth < p->auth)
		return -1;
	int i;
	
	for(i=p->wpos;i<p->wpos+len;i++) {
		p->dat[i]=data[i-p->wpos];}
	p->rpos=p->wpos;
	p->wpos+=len;
	sti();
//	signal_all(SIG_PIPE_WRITTEN, p);
	return 0;
}
